package com.example.qxfw.common.util;


import com.dmgis.entity.DmGridInfo;
import com.dmgis.weblib.GridAnalysis;
import com.example.qxfw.common.entity.xt.ContourSetting;
import com.example.qxfw.qxxx.entity.GridDataPicAndXY;
import com.example.qxfw.mongodb.qx.entity.QxGridFile;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.File;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.util.*;

/************************************
 *
 * @author : HuangDeYin Jolly
 * @since : JDK 11
 * @Date : 2023/8/17  星期四   11:07
 * @description : 处理grid的问题
 ***************************************/
@Component
public class GridUtil {

    @Autowired
    private ByteToFileUtil byteToFileUtil;

    /**
     * 处理格点数据，生成经纬度值列表。
     *
     * @param qxGridFile 包含格点数据的 QxGridFile 对象
     * @return 经纬度值列表，包含每个格点的经度、纬度和对应值
     * @throws IOException 如果在处理过程中发生 I/O 异常
     */
    public Map<String, Object> processGridData(QxGridFile qxGridFile) throws IOException {
        // 获取格点数据的字节数组
        byte[] data = qxGridFile.getData();
        // 生成文件名，以格点文件的 ID 作为基础
        String fileName = qxGridFile.get_id() + ".grid";
        // 将字节数组写入临时格点文件并获取文件路径
        String gridFile = byteToFileUtil.byteArrayToGridFile(data, fileName);
        System.err.println(gridFile);

        // 创建 GridAnalysis 对象并打开格点文件
        GridAnalysis grid = new GridAnalysis();
        grid.openFile(gridFile);

        DmGridInfo gridInfo = grid.getGridInfo();
        int rows = gridInfo.getRows();
        int cols = gridInfo.getCols();
        // 创建存储经纬度值的列表
        DecimalFormat df = new DecimalFormat("#.0000");
        Map<String, Object> rltmap = new HashMap<>();
        Double[] lons = new Double[rows * cols];
        Double[] lats = new Double[rows * cols];
        Double[] vals = new Double[rows * cols];
        // 循环遍历格点数据，并生成经纬度值列表
        for (int i = 0; i < rows; i++) {
            for (int j = 0; j < cols; j++) {
                // 获取格点值
                float floatValue = grid.getValue(i, j);
                BigDecimal value = new BigDecimal(String.valueOf(floatValue));
                value = value.setScale(1, RoundingMode.HALF_UP); // 设置保留一位小数
                // 根据行号和 GridInfo 获取纬度值
                double latitudeForRow = getLatitudeForRow(i, gridInfo);
                // 根据列号和 GridInfo 获取经度值
                double longitudeForCol = getLongitudeForCol(j, gridInfo);
                lons[i * cols + j] = Double.parseDouble(df.format(latitudeForRow));
                lats[i * cols + j] = Double.parseDouble(df.format(longitudeForCol));
                vals[i * cols + j] = Double.parseDouble(value.toString());
            }
        }
        rltmap.put("lats", lons);
        rltmap.put("lons", lats);
        rltmap.put("vals", vals);
        rltmap.put("colnum", cols);
        rltmap.put("rownum", rows);
        // 返回经纬度值列表
        return rltmap;
    }

    /**
     * 处理格点数据，生成图片。
     *
     * @param qxGridFile 包含格点数据的 QxGridFile 对象
     * @return 经纬度值列表，包含每个格点的经度、纬度和对应值
     * @throws IOException 如果在处理过程中发生 I/O 异常
     */
    public byte[] processGridDataPic(QxGridFile qxGridFile, List<ContourSetting> contourSettings) throws IOException {
        // 获取格点数据的字节数组
        byte[] data = qxGridFile.getData();
        // 生成文件名，以格点文件的 ID 作为基础
        String fileName = qxGridFile.get_id() + ".grid";
        // 将字节数组写入临时格点文件并获取文件路径
        String gridFile = byteToFileUtil.byteArrayToGridFile(data, fileName);
        System.err.println(gridFile);

        // 创建 GridAnalysis 对象并打开格点文件
        GridAnalysis grid = new GridAnalysis();
        grid.openFile(gridFile);

        //计算最大最小值，配合自动分级做
       // Arrays.sort(gridAnalysis.getfValS());
       // gridInfo.setyMin(gridAnalysis.getfValS()[0]);
       // gridInfo.setxMax(gridAnalysis.getfValS()[gridAnalysis.getfValS().length - 1]);
       //  grid.drawGridInfo(10, file.getAbsolutePath(), null, null,10);//绘制图片

        //按照国标分级
        ArrayList<Float> colorlist = new ArrayList<Float>();
        ArrayList<String> colors = new ArrayList<String>();
        for (ContourSetting set : contourSettings) {
            colorlist.add(Float.parseFloat(set.getElementvalue().toString()));

            int color = set.getElementcolor();
            int b = color & 0xff;
            int g = (color >> 8) & 0xff;
            int r = (color >> 16) & 0xff;
            String color16 = String.format("#%02X%02X%02X", r, g, b);
            colors.add(color16);
        }

        File file = FileUtil.getFile("png");
        grid.drawGridInfo(10, file.getAbsolutePath(), colorlist, colors, 15);//绘制图片
        byte[] filedata = FileUtil.getBytesByFile(file.getAbsolutePath());
        file.delete();//只保留data，文件直接删除
        return filedata;
    }

    /**
     * 处理格点数据，生成图片。
     *
     * @param qxGridFile 包含格点数据的 QxGridFile 对象
     * @return 经纬度值列表，包含每个格点的经度、纬度和对应值
     * @throws IOException 如果在处理过程中发生 I/O 异常
     */
    public GridDataPicAndXY processGridDataPicAndXY(QxGridFile qxGridFile, List<ContourSetting> contourSettings) throws IOException {
        // 获取格点数据的字节数组
        byte[] data = qxGridFile.getData();
        // 生成文件名，以格点文件的 ID 作为基础
        String fileName = qxGridFile.get_id() + ".grid";
        // 将字节数组写入临时格点文件并获取文件路径
        String gridFile = byteToFileUtil.byteArrayToGridFile(data, fileName);
        System.err.println(gridFile);
        // 创建 GridAnalysis 对象并打开格点文件
        GridAnalysis grid = new GridAnalysis();
        grid.openFile(gridFile);
        //计算最大最小值，配合自动分级做
//        Arrays.sort(gridAnalysis.getfValS());
//        gridInfo.setyMin(gridAnalysis.getfValS()[0]);
//        gridInfo.setxMax(gridAnalysis.getfValS()[gridAnalysis.getfValS().length - 1]);
        //grid.drawGridInfo(10, file.getAbsolutePath(), null, null,10);//绘制图片
        //按照国标分级
        ArrayList<Float> colorlist = new ArrayList<Float>();
        ArrayList<String> colors = new ArrayList<String>();
        for (ContourSetting set : contourSettings) {
            colorlist.add(Float.parseFloat(set.getElementvalue().toString()));
            int color = set.getElementcolor();
            int b = color & 0xff;
            int g = (color >> 8) & 0xff;
            int r = (color >> 16) & 0xff;
            String color16 = String.format("#%02X%02X%02X", r, g, b);
            colors.add(color16);
        }
        File file = FileUtil.getFile("png");
        grid.drawGridInfo(10, file.getAbsolutePath(), colorlist, colors, 15);//绘制图片
        byte[] filedata = FileUtil.getBytesByFile(file.getAbsolutePath());
        file.delete();//只保留data，文件直接删除
        GridDataPicAndXY gridDataPicAndXY = new GridDataPicAndXY(filedata, grid.getGridInfo());
        return gridDataPicAndXY;
    }

    /**
     * 根据行号获取对应的纬度坐标
     *
     * @param row  行号
     * @param info Grid信息对象
     * @return 纬度坐标
     */
    public static double getLatitudeForRow(int row, DmGridInfo info) {
        double deltY = (info.getyMax() - info.getyMin()) / (info.getRows() - 1);
        return info.getyMin() + row * deltY;
    }

    /**
     * 根据列号获取对应的经度坐标
     *
     * @param col  列号
     * @param info Grid信息对象
     * @return 经度坐标
     */
    public static double getLongitudeForCol(int col, DmGridInfo info) {
        double deltX = (info.getxMax() - info.getxMin()) / (info.getCols() - 1);
        return info.getxMin() + col * deltX;
    }

}
